"""--------------------------------------------------------------------------------------------------
Filename:   viewplot.py
Author:     Chris Chester
Date:       4 Decemeber 2012
Description:
    Plotting module for biofeedback reviewing application.
    Contains the GUI layer and plotting functions.
--------------------------------------------------------------------------------------------------"""

import matplotlib

import numpy as np
import pylab
import wx, traceback
from decimal import Decimal
from reviewplotpanel import ReviewPlotControl, ReviewPlotPanel
import time


#===============================================================================
# CLASS: ViewPlot(wx.Frame)
#    Plotting class for reviewing sessions.
#    This class owns the data arrays containing the bioimpedance and time values for
#    the plot points.
#===============================================================================
class ViewPlot(wx.Frame):
    def __init__(self, app, parent=None, id=-1, title="View plot frame"):
        wx.Frame.__init__(self, parent, id, title, size=(800, 600))
        self.app = app
        self.top_panel = wx.Panel(self, -1)        # top-level panel for frame
        self.plotpanel = ReviewPlotPanel(parent=self.top_panel, color=None, dpi=80, id=-1)
        self.plotctrl = ReviewPlotControl(parent=self.top_panel, id=-1, app=app)
        self.start_time = 0
        self.manual_y_axis = False
        self.__do_layout()
        self.__setup_plot()
        
    def __do_layout(self):
        ''' Sets layout for Viewplot GUI '''
        sizer_frame = wx.BoxSizer(wx.VERTICAL)  # sizer for frame
        sizer_main = wx.BoxSizer(wx.VERTICAL)
        sizer_main.Add(self.plotpanel, 1, wx.EXPAND | wx.ALL, 0)
        sizer_main.Add(self.plotctrl, 0, wx.EXPAND | wx.ALL, 25)
        self.top_panel.SetSizer(sizer_main)
        sizer_frame.Add(self.top_panel, 1, wx.EXPAND, 0)
        self.SetSizer(sizer_frame)
        sizer_frame.Fit(self)
        self.ShowFullScreen(not self.IsFullScreen(), wx.FULLSCREEN_ALL)
        self.Layout()
        
    def __setup_plot(self):
        ''' Sets up the impedance plot'''
        
        # Instantiate a matplotlib axes object
        self.axes = self.plotpanel.figure.add_subplot(111)    # self.axes is an instance of an Axes object
        self.axes.set_axis_bgcolor(self.app.cfg.plotBackColour)
        self.axes.set_title('Bioimped level', size=20)
        self.axes.set_xlabel('Time (s)')
        self.axes.set_ylabel('Pressure')
        self.axes.set_autoscale_on(False)
        self.redo_yauto = True
        
        self.xaxis_max = 10
        self.yaxis_max = 2000

        pylab.setp(self.axes.get_xticklabels(), fontsize=13)
        pylab.setp(self.axes.get_yticklabels(), fontsize=13)
        
        #self.axes.set_xbound(lower=0, upper=self.xaxis_max)
        #self.axes.set_ybound(lower=0, upper= self.yaxis_max)
        self.axes.set_ylim(auto = True)
        
        # Initialise data arrays to be added to later
        self.ch1_x_data_total = self.app.hdls.loaded_xvalues1
        self.ch1_y_data_total = self.app.hdls.loaded_yvalues1
        self.ch2_x_data_total = self.app.hdls.loaded_xvalues2
        self.ch2_y_data_total = self.app.hdls.loaded_yvalues2
        
        # Gets the values for the first screen of the data
        self.ch1_x_data = [i for i in self.ch1_x_data_total if i <= self.xaxis_max]
        
        len_data = len(self.ch1_x_data)
        
        self.ch1_y_data = self.ch1_y_data_total[:len_data]
        self.ch2_x_data = self.ch2_x_data_total[:len_data]
        self.ch2_y_data = self.ch2_y_data_total[:len_data]
        
        # Plot the data and grab a reference to the line added
        self.emgplot = self.axes.plot(self.ch1_x_data,
                                      self.ch1_y_data,
                                      'g',
                                      self.ch2_x_data,
                                      self.ch2_y_data,
                                      'b',
                                      animated=True)
                
        self.init_plot()
        self.draw()
        
    def __draw_impedance(self, init=False):
        ''' Draws a plot of the impedance levels '''
        self.__remove_target()


        # reset the axes
        #self.axes.set_xbound(lower=0, upper=self.app.cfg._x_axis_max)
        #self.axes.set_ybound(lower=0, upper=self.app.cfg._y_axis_max)
        #self.axes.set_ylim(auto = True)
            
    def draw_grid(self, boo):
        # Turn the plot grid on or off
        if boo:
            self.axes.grid(True, color='gray', which='both')
            
        else:
            self.axes.grid(False)
        

    def init_plot(self):
        """ Initial plot setup at the start of calibration and trials
        """
        self.reset_plot()
        
        
    def show_plot(self, boo):
        # set plot visibility and update controls
        self.app.ctrl.chkbx_ctrl.cb_plot.SetValue(boo)
        self.emgplot.set_visible(boo)
        
    def reset_plot(self):
        # Clears the plot frame and resets data arrays
        self.getBackground = True
        
        # reset data arrays
                # Gets the values for the first screen of the data
        self.ch1_x_data = [i for i in self.ch1_x_data_total if i <= self.xaxis_max] 
        len_data = len(self.ch1_x_data)
        
        self.ch1_y_data = self.ch1_y_data_total[:len_data]
        self.ch2_x_data = self.ch2_x_data_total[:len_data]
        self.ch2_y_data = self.ch2_y_data_total[:len_data]
    
        self.emgplot = self.axes.plot(self.ch1_x_data,
                                      self.ch1_y_data,
                                      'g',
                                      self.ch2_x_data,
                                      self.ch2_y_data,
                                      'b',
                                      animated=True)

        # reset the axes
        #self.axes.set_xbound(lower=0, upper=self.app.cfg._x_axis_max)
        #self.axes.set_ybound(lower=0, upper=self.app.cfg._y_axis_max)
        #self.axes.set_ylim(auto = True)
        
        # Set grid lines
        self.draw_grid(self.plotctrl.cb_grid.GetValue())

        # Redraw the plot

        try:
            canvas = self.plotpanel.canvas
            self.background = canvas.copy_from_bbox(self.axes.bbox)
            
        except:
            print traceback.format_exc()
        self.Refresh()
        
        
    def draw(self):
        # Main draw function
        #    - Draws the changes in the model to the screen
           
               
        #self.axes.set_ybound(lower=0, upper=y_axis_max)
        #self.axes.set_ylim(auto = True)
        self.axes.set_xbound(lower = self.ch1_x_data[0], upper = self.ch1_x_data[len(self.ch1_x_data)-1])
        
        self.getBackground = True # Redo Visual Axis
        
        try:        # main canvas update function call
            
            # If the Manual Y axis button is pressed
            if self.manual_y_axis:
                y_min = int(self.plotctrl.manual_text_min.GetValue())
                y_max = int(self.plotctrl.manual_text_max.GetValue())
                self.axes.set_ylim(auto = False)
                self.axes.set_ybound(lower= y_min, upper= y_max)
                self.getBackground = True 
            else:
                self.axes.set_ylim(auto = True)             
            
            # Restore the background from the current plot values 
            if self.getBackground:
                canvas = self.plotpanel.canvas
                canvas.draw()
                self.background = canvas.copy_from_bbox(self.axes.bbox)
                self.getBackground = False 
                
            
            self.plotpanel.canvas.restore_region(self.background)
            # Set the plot data
            self.emgplot = self.axes.plot(self.ch1_x_data,
                                          self.ch1_y_data,
                                          'g',
                                          self.ch2_x_data,
                                          self.ch2_y_data,
                                          'b',
                                          animated=False)
            # Update the emg plot
            
                #self.axes.set_ylim(auto = True)
            
            self.axes.draw_artist(self.emgplot[0])
            self.axes.draw_artist(self.emgplot[1])
            # Redraw axes rectangle
            self.plotpanel.canvas.blit(self.axes.bbox)
            
        except RuntimeError:
            print traceback.format_exc()
            
        except:
            print traceback.format_exc()
                    
    
    def get_axes(self):
        return self.axes
                    
        
# End of viewplot.py
